package com.huirui.server.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huirui.server.constant.CouponConstant;
import com.huirui.server.constant.CouponStatus;
import com.huirui.server.mapper.CouponMapper;
import com.huirui.server.pojo.dto.CouponDto;
import com.huirui.server.pojo.entity.Coupon;
import com.huirui.server.pojo.result.PageResult;
import com.huirui.server.service.CouponService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author yujun
 * @description 针对表【t_coupon】的数据库操作Service实现
 * @createDate 2025-10-28 22:32:33
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon>
        implements CouponService {

    @Override
    public void addNewCoupon(CouponDto couponDto) {
        Coupon coupon = new Coupon();
        coupon.setName(couponDto.getName());
        coupon.setDistributionStartTime(couponDto.getDistributionStartTime());
        coupon.setDistributionEndTime(couponDto.getDistributionEndTime());
        coupon.setCouponType(couponDto.getCouponType());
        if (coupon.getCouponType() == CouponConstant.CATEGORY_COUPON) {
            // 品类券
            coupon.setCategoryIds(StringUtils.join(couponDto.getCategoryIds(), ","));
        } else if (coupon.getCouponType() == CouponConstant.PRODUCT_COUPON) {
            // 商品券
            coupon.setProductIds(StringUtils.join(couponDto.getProductIds(), ","));
        }
        coupon.setDenomination(couponDto.getDenomination());
        coupon.setHasThreshold(couponDto.getHasThreshold());
        if (coupon.getHasThreshold() == CouponConstant.HAS_THRESHOLD) {
            coupon.setThreshold(couponDto.getThreshold());
        }
        coupon.setExpiryType(couponDto.getExpiryType());
        if (coupon.getExpiryType() == CouponConstant.EXPIRE_DAYS) {
            coupon.setValidDays(couponDto.getValidDays());
        } else if (coupon.getExpiryType() == CouponConstant.EXPIRE_RANGE) {
            coupon.setAvailableStartTime(couponDto.getAvailableStartTime());
            coupon.setAvailableEndTime(couponDto.getAvailableEndTime());
        }
        coupon.setHasQuantityLimit(couponDto.getHasQuantityLimit());
        if (coupon.getHasQuantityLimit() == CouponConstant.HAS_QUANTITY_LIMIT) {
            coupon.setQuantityLimit(couponDto.getQuantityLimit());
        }
        coupon.setUserMaxCollectionLimit(couponDto.getUserMaxCollectionLimit());
        coupon.setCouponStatus(couponDto.getCouponStatus());
        coupon.setCreateTime(LocalDateTime.now());
        coupon.setUpdateTime(LocalDateTime.now());
        coupon.setDistributedQuantity(0);
        save(coupon);
    }

    @Override
    public PageResult<CouponDto> listCoupon(String keyword, Integer status, Long page, Long pageSize) {
        PageResult<CouponDto> res = new PageResult<>();
        var couponList = lambdaQuery()
                .like(StringUtils.isNotBlank(keyword), Coupon::getName, keyword)
                .eq(ObjectUtils.isNotEmpty(status), Coupon::getCouponStatus, status)
                .orderByDesc(Coupon::getUpdateTime)
                .page(new Page<>(page, pageSize));
        List<CouponDto> couponDtoList = new ArrayList<>();
        couponList.getRecords().forEach(coupon -> {
            CouponDto couponDto = new CouponDto();
            couponDto.setName(coupon.getName());
            couponDto.setId(coupon.getId());
            couponDto.setDistributionStartTime(coupon.getDistributionStartTime());
            couponDto.setDistributionEndTime(coupon.getDistributionEndTime());
            couponDto.setCouponType(coupon.getCouponType());
            if (coupon.getCouponType() == CouponConstant.CATEGORY_COUPON) {
                List<Long> categoryIds = Arrays.stream(StringUtils.split(coupon.getCategoryIds(), ",")).map(Long::valueOf).toList();
                couponDto.setCategoryIds(categoryIds);
            }
            if (coupon.getCouponType() == CouponConstant.PRODUCT_COUPON) {
                List<Long> productIds = Arrays.stream(StringUtils.split(coupon.getProductIds(), ",")).map(Long::valueOf).toList();
                couponDto.setProductIds(productIds);
            }
            couponDto.setDenomination(coupon.getDenomination());
            couponDto.setHasThreshold(coupon.getHasThreshold());
            if (coupon.getHasThreshold() == CouponConstant.HAS_THRESHOLD) {
                couponDto.setThreshold(coupon.getThreshold());
            }
            couponDto.setExpiryType(coupon.getExpiryType());
            if (coupon.getExpiryType() == CouponConstant.EXPIRE_DAYS) {
                couponDto.setValidDays(coupon.getValidDays());
            } else if (coupon.getExpiryType() == CouponConstant.EXPIRE_RANGE) {
                couponDto.setAvailableStartTime(coupon.getAvailableStartTime());
                couponDto.setAvailableEndTime(coupon.getAvailableEndTime());
            }
            couponDto.setHasQuantityLimit(coupon.getHasQuantityLimit());
            if (coupon.getHasQuantityLimit() == CouponConstant.HAS_QUANTITY_LIMIT) {
                couponDto.setQuantityLimit(coupon.getQuantityLimit());
            }
            couponDto.setUserMaxCollectionLimit(coupon.getUserMaxCollectionLimit());
            couponDto.setCouponStatus(coupon.getCouponStatus());
            couponDto.setDistributedQuantity(Long.valueOf(coupon.getDistributedQuantity()));
            if (couponDto.getHasQuantityLimit() == CouponConstant.HAS_QUANTITY_LIMIT) {
                couponDto.setPendingDistributionQuantity((long) (coupon.getQuantityLimit() - coupon.getDistributedQuantity()));
            }
            couponDto.setCreateTime(coupon.getCreateTime());
            couponDtoList.add(couponDto);
        });
        res.setPages(couponList.getPages());
        res.setTotal(couponList.getTotal());
        res.setSize(couponList.getSize());
        res.setCurrent(couponList.getCurrent());
        res.setRecords(couponDtoList);
        return res;
    }

    @Override
    public void updateCoupon(CouponDto couponDto) {
        Long couponId = couponDto.getId();
        // 查询当前已被领取多少张
        Coupon old = lambdaQuery()
                .eq(Coupon::getId, couponId)
                .select(Coupon::getDistributedQuantity, Coupon::getCreateTime)
                .one();
        removeById(couponId);
        Coupon coupon = new Coupon();
        coupon.setName(couponDto.getName());
        coupon.setDistributionStartTime(couponDto.getDistributionStartTime());
        coupon.setDistributionEndTime(couponDto.getDistributionEndTime());
        coupon.setCouponType(couponDto.getCouponType());
        if (coupon.getCouponType() == CouponConstant.CATEGORY_COUPON) {
            // 品类券
            coupon.setCategoryIds(StringUtils.join(couponDto.getCategoryIds(), ","));
        } else if (coupon.getCouponType() == CouponConstant.PRODUCT_COUPON) {
            // 商品券
            coupon.setProductIds(StringUtils.join(couponDto.getProductIds(), ","));
        }
        coupon.setDenomination(couponDto.getDenomination());
        coupon.setHasThreshold(couponDto.getHasThreshold());
        if (coupon.getHasThreshold() == CouponConstant.HAS_THRESHOLD) {
            coupon.setThreshold(couponDto.getThreshold());
        }
        coupon.setExpiryType(couponDto.getExpiryType());
        if (coupon.getExpiryType() == CouponConstant.EXPIRE_DAYS) {
            coupon.setValidDays(couponDto.getValidDays());
        } else if (coupon.getExpiryType() == CouponConstant.EXPIRE_RANGE) {
            coupon.setAvailableStartTime(couponDto.getAvailableStartTime());
            coupon.setAvailableEndTime(couponDto.getAvailableEndTime());
        }
        coupon.setHasQuantityLimit(couponDto.getHasQuantityLimit());
        if (coupon.getHasQuantityLimit() == CouponConstant.HAS_QUANTITY_LIMIT) {
            coupon.setQuantityLimit(couponDto.getQuantityLimit());
        }
        coupon.setUserMaxCollectionLimit(couponDto.getUserMaxCollectionLimit());
        coupon.setCouponStatus(couponDto.getCouponStatus());
        coupon.setCreateTime(old.getCreateTime());
        coupon.setUpdateTime(LocalDateTime.now());
        coupon.setDistributedQuantity(old.getDistributedQuantity());
        save(coupon);
    }

    @Override
    public void deleteCoupon(Long couponId) {
        lambdaUpdate()
                .eq(Coupon::getId, couponId)
                .set(Coupon::getCouponStatus, CouponStatus.DELETED)
                .update();
    }
}




